import { onBeforeUnmount, ref } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';

import { message, Modal } from 'ant-design-vue';

import { seatGetAvailable } from '#/api/config/seat';
import { loadScripts } from '#/utils/file';

const initializing = ref(false); // 天润融通电话条初始化中
const initialized = ref(false); // 天润融通电话条初始化成功
const isLogin = ref(false); // 坐席登录成功
const loading = ref(true); // 登录中
const isCalling = ref(false); // 是否通话中
const agentInfo = ref<Record<any, any>>();
const activePhone = ref<null | string>(null); // 当前通话的号码
const tip = ref<string>(''); // 用于tooltip的提示内容
let clinkToolbar: any;

interface UseClinkCallOptions {
  autoLogin?: boolean;
  onLogined?: (code: number) => void;
  onLogout?: () => void;
  onBusy?: (uniqueId: string) => void;
  onIdle?: () => void;
}

// 标记是否已绑定页面关闭确认事件
let hasBindUnloadEvent = false;

function _logout() {
  if ((window as any).ClinkAgent && isLogin.value) {
    ClinkAgent.logout({ logoutMode: 1, chatClose: 1, removeBinding: 0 });
  }
}

// 页面关闭前确认提示事件
function handleBeforeUnload(event: BeforeUnloadEvent) {
  _logout();

  // 弹出确认提示（部分浏览器会忽略自定义文本）
  event.preventDefault();
  event.returnValue = ''; // 这句是必要的，才能触发确认框
}

// 解绑页面关闭前确认提示事件
function disposeUnloadEvent() {
  if (hasBindUnloadEvent) {
    window.removeEventListener('beforeunload', handleBeforeUnload);
    hasBindUnloadEvent = false;
  }
}

onBeforeUnmount(() => {
  disposeUnloadEvent();
});

export function useClinkCall(useOptions?: UseClinkCallOptions) {
  // const tip = ref<string>(''); // 用于tooltip的提示内容
  async function setupClinkToolbar(container: HTMLElement | null = null) {
    // 异步加载天润融通呼叫电话条插件依赖js
    await loadScripts(
      [
        'https://resource.iteschina.com/iteschina/common/js/clink-client.js',
        'https://resource.iteschina.com/iteschina/common/js/ClinkToolbar.umd.min.js',
      ],
      { sequential: true },
    );

    if ((window as any).ClinkToolbar) {
      // 避免重复初始化
      if (clinkToolbar) {
        initialized.value = true;
        return;
      }

      // 隐藏登录界面、隐藏登录界面中的部分版块以及话务管理参数配置
      const options = {
        isAutoLogin: true, // 隐藏登录界面
        // 隐藏登录界面中的部分版块配置
        toolbarMsgShowConfiguration: {
          showEnterprise: false, // 展示企业编码、座席工号、密码
          showTel: false, // 展示电话类型和电话号码
          showAgentInitStatus: false, // 展示座席初始状态
          showLogout: true, // 展示签出按钮
          showTelInput: true, // 登录状态下是否显示号码输入框、默认为true
          showCallingBth: true, // 登录状态下是否显示呼叫按钮、默认为true
          showChangeBindTel: false, // 登录状态下是否显示换绑定电话配置、默认为false
        },
        // 话务管理配置
        showHold: true, // 支持保持
        showConsult: true, // 支持咨询
        showTransfer: true, // 支持转移
        showSatisfaction: true, // 支持满意度
        showMute: true, // 支持静音
        debug: true, // 是否开启debug 默认开启
      };

      initializing.value = true;
      loading.value = true;
      clinkToolbar = new ClinkToolbar(
        options, // 登录方式和话务管理参数配置
        container, // 为空时默认插入body中
        () => {
          console.log('电话条初始化成功', clinkToolbar);
          initialized.value = true;
          initializing.value = false;
          if (useOptions?.autoLogin) {
            login();
          } else {
            loading.value = false;
          }
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.ResponseType.LOGIN,
        (e: any) => {
          console.log('登录后的事件监听:', e);
          // if (e.code === 0) {
          //   isLogin.value = true;
          //   useOptions?.onLogined?.(e.code);
          // }
          if (e.code === -1) {
            // 登录失败
            isLogin.value = false;
            useOptions?.onLogined?.(e.code);
          }
          // loading.value = false;
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.EventType.SIP_REGISTERED,
        (e: any) => {
          console.log('软电话SIP_REGISTERED事件:', e);
          if (e.code === 0) {
            isLogin.value = true;
            useOptions?.onLogined?.(e.code);
          }
          loading.value = false;
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.ResponseType.LOGOUT,
        (e: any) => {
          console.log('退出后的事件监听:', e);
          if (e.code === 0 && e.reqType === 'logout') {
            isLogin.value = false;
            isCalling.value = false;
            useOptions?.onLogout?.();
          }
        },
      );

      clinkToolbar.userCustomEvent.on(ClinkAgent.EventType.STATUS, (e: any) => {
        console.log('座席状态事件回调:', e);
        if (e.code === 'OFFLINE' && e.loginStatus === 0) {
          // tip.value = '当前坐席已离线';
          isLogin.value = false;
          isCalling.value = false;
        }
        if (e.code === 'CALLING' && e.loginStatus === 1) {
          // 开始呼叫中，比响铃事件回调RINGING早
          tip.value = '开始呼叫中';
        }
        if (e.code === 'RINGING' && e.loginStatus === 1) {
          // 外呼振铃，执行于响铃事件回调RINGING之后
          tip.value = '外呼振铃中';
        }
        if (e.code === 'BUSY' && e.loginStatus === 1) {
          useOptions?.onBusy?.(e.mainUniqueId);

          // 外呼通话，执行于预览外呼客户响铃事件回调之前
          if (e.action === 'busyAgentOb') {
            // 外呼座席接通，呼叫客户中
            tip.value = '外呼座席接通，呼叫客户中';
          }
          if (e.action === 'ringingCustomerOb') {
            // 外呼客户响铃
            tip.value = '外呼客户响铃';
          }
          if (e.action === 'busyOb') {
            // 外呼客户接听，双方通话
            tip.value = '正在通话中';
          }
        }
        if (e.code === 'IDLE' && e.loginStatus === 1) {
          // 进入空闲状态（挂断通话后会进入）
          // tip.value = '';
          isCalling.value = false;
          useOptions?.onIdle?.();
        }
      });

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.EventType.PREVIEW_OUTCALL,
        (e: any) => {
          console.log('预览外呼事件回调', e);
          if (e.code === -1) {
            /**
             * 外呼失败，运营商禁呼：
             *  - 超过中继频次限制,限制开始时间:2025-06-30 10:02:17 | 呼叫超频限制
             *  -
             *  ...
             */
            tip.value = `呼叫失败原因：${e.msg}`;
            hangup();
          }
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.EventType.PREVIEW_OUTCALL_RINGING,
        (e: any) => {
          console.log('预览外呼客户响铃事件回调:', e);
          if (e.code === 'BUSY') {
            useOptions?.onBusy?.(e.mainUniqueId);
            /**
             * 外呼振铃
             */
            if (e.action === 'busyAgentOb') {
              // 外呼座席接通，呼叫客户中
            }
            if (e.action === 'ringingCustomerOb') {
              // 外呼客户响铃
            }
            if (e.action === 'busyOb') {
              // 外呼客户接听，双方通话
            }
          }
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.EventType.PREVIEW_OUTCALL_BRIDGE,
        (e: any) => {
          console.log('预览外呼客户接听事件回调:', e);
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.EventType.RINGING,
        (e: any) => {
          console.log('响铃事件回调:', e);
          if (e.event === 'ringing') {
            /**
             * 外呼振铃
             * e.customerNumber 被呼客户号码
             * e.customerProvince 被呼客户号码所属省份
             * e.customerCity 被呼客户号码所属城市
             * e.mainUniqueId 通话记录唯一ID
             * e.xNumber 呼叫方号码（客户侧显示的号码）
             */
          }
        },
      );

      clinkToolbar.userCustomEvent.on(
        ClinkAgent.EventType.KICKOUT,
        (e: any) => {
          console.log('被踢下线事件回调:', e);
        },
      );
    }
  }

  function call(phone: string) {
    if (isCalling.value || !phone) return;
    isCalling.value = true;
    activePhone.value = phone;
    if ((window as any).ClinkAgent && isLogin.value) {
      console.log(`📞 正在呼叫：${phone}`);
      /**
       * 预览外呼文档
       * https://develop.clink.cn/develop/web/toolbar.html#_%E9%A2%84%E8%A7%88%E5%A4%96%E5%91%BC
       * @param requestUniqueId?:string 请求唯一标识，不传会自动生成，会存入通话记录表中
       */
      ClinkAgent.previewOutcall({ tel: phone });
    }
  }

  async function login(phoneNumber?: string) {
    if (!hasBindUnloadEvent) {
      window.addEventListener('beforeunload', handleBeforeUnload);
      hasBindUnloadEvent = true;
    }

    if ((window as any).ClinkAgent) {
      console.log('坐席开始登录login....');
      if (phoneNumber) {
        activePhone.value = phoneNumber;
      }
      loading.value = true;
      try {
        const agent = await seatGetAvailable();
        // clinkToolbar.setLoginNecessaryParams(loginParams);
        if (agent) {
          agentInfo.value = agent;
          ClinkAgent.login({
            ...agent,
            loginStatus: 1,
          });
        } else {
          tip.value = '暂无可用坐席';
          message.warning('暂未配置或无可用坐席');
          loading.value = false;
        }
      } catch (error) {
        console.log(error);
        tip.value = '获取坐席失败';
        loading.value = false;
      }
    }
  }

  function hangup() {
    console.log('🔚 挂断通话');
    if ((window as any).ClinkAgent && isLogin.value) {
      ClinkAgent.previewOutcallCancel({});
    }
    isCalling.value = false;
    loading.value = false;
    // activePhone.value = null;
  }

  function logout() {
    _logout();
  }

  function onBeforeRouteLeaveCallPage(callback?: any) {
    onBeforeRouteLeave((_to, _from, next) => {
      if (isLogin.value) {
        Modal.confirm({
          title: '温馨提示',
          content: `退出当前页面，呼叫坐席将自动下线，确定要离开吗？`,
          okText: '确认离开',
          onOk: async () => {
            callback && callback();
            logout();
            next();
          },
          onCancel: () => {
            next(false);
          },
        });
      } else {
        callback && callback();
        next();
      }
    });
  }

  return {
    initializing,
    initialized,
    isLogin,
    loading,
    tip,
    isCalling,
    activePhone,
    agentInfo,
    setupClinkToolbar,
    login,
    call,
    hangup,
    logout,
    onBeforeRouteLeaveCallPage,
  };
}
